import React from "react";
import { useI18n, toApiLanguageCode } from '@/utils/in18';
import { request } from '@/utils/request';
import axios from 'axios';
import { getStoredBearerToken, hasStoredToken } from '@/utils/auth';
import { openLoginModal, setLoginReturnState } from '@/componets/loginModel';

type TemplateCard = {
  id: number;
  title: string;
  desc?: string;
  src?: string;
  raw?: any;
  role_prompt?: string;
} | null;

type InformationListProps = {
  /** 父组件传入的卡片数据（包含 template 信息） */
  card: TemplateCard;
  /** 当信息弹窗可见时才进行数据与滚动监听 */
  visible: boolean;
  /** 滚动容器（父弹窗的根容器，用于监听滚动触底加载） */
  scrollContainerRef: React.RefObject<HTMLDivElement>;
  /** 当内部 works 变更时，通知父组件（用于父级图片预览合并主图） */
  onWorksChange?: (works: any[]) => void;
  /** 当点击图片时，通过 id 通知父组件打开预览 */
  onOpenPreviewById?: (id: string | number) => void;
};

// 将字符串按显示宽度截断：全角字符按2，半角字符按1
const isFullWidthChar = (ch: string): boolean => {
  try {
    return /[\u1100-\u115F\u2E80-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE6F\uFF00-\uFF60\uFFE0-\uFFE6]/u.test(ch);
  } catch {
    return false;
  }
};

const sliceByDisplayWidth = (input: string, maxFullWidthChars: number): string => {
  const source = input || '';
  const maxUnits = Math.max(0, maxFullWidthChars) * 2;
  let used = 0;
  let out = '';
  for (const ch of source) {
    const w = isFullWidthChar(ch) ? 2 : 1;
    if (used + w > maxUnits) break;
    out += ch;
    used += w;
  }
  return out === source ? out : out + '…';
};

const InformationList: React.FC<InformationListProps> = ({ card, visible, scrollContainerRef, onWorksChange, onOpenPreviewById }) => {
  // 本组件内部管理“同款作品”列表与其相关的加载、分页、点赞等逻辑
  const { t, locale } = useI18n();

  // 作品数组与分页状态
  const [works, setWorks] = React.useState<any[]>([]);
  const [page, setPage] = React.useState<number>(1);
  const [pageSize] = React.useState<number>(6);
  const [total, setTotal] = React.useState<number>(0);
  const [loading, setLoading] = React.useState<boolean>(false);
  const [noMore, setNoMore] = React.useState<boolean>(false);

  // 点赞/计数本地缓存
  const [likesState, setLikesState] = React.useState<Record<number, { liked: boolean; count: number }>>({});
  // 网格图片骨架加载映射
  const [gridLoadedMap, setGridLoadedMap] = React.useState<Record<number, boolean>>({});
  // 当第一页为空时显示友好提示
  const [noUserGenerated, setNoUserGenerated] = React.useState<boolean>(false);

  // 当 works 变化时，通知父级（用于父级预览合并主图）
  React.useEffect(() => {
    try { onWorksChange && onWorksChange(works); } catch { }
  }, [works, onWorksChange]);

  // 切换点赞
  const toggleLike = React.useCallback(async (id: number) => {
    if (!hasStoredToken()) {
      try { setLoginReturnState({ type: 'infoCardMobile', url: window.location.href, templateCard: card, restoreScrollToId: id }); } catch { }
      try { openLoginModal(); } catch { }
      return;
    }
    const prevEntry = likesState[id] || { liked: false, count: 0 };
    setLikesState((prev) => {
      const cur = prev[id] || { liked: false, count: 0 };
      const newLiked = !cur.liked;
      const newCount = cur.count + (newLiked ? 1 : -1);
      return { ...prev, [id]: { liked: newLiked, count: newCount } };
    });

    try {
      const authHeader = getStoredBearerToken();
      if (!authHeader) {
        setLikesState((prev) => ({ ...prev, [id]: prevEntry }));
        try { setLoginReturnState({ type: 'infoCardMobile', url: window.location.href, templateCard: card, restoreScrollToId: id }); } catch { }
        try { openLoginModal(); } catch { }
        return;
      }
      const langCode = toApiLanguageCode(locale as any);
      const apiBase = (import.meta as any).env?.VITE_API || '';
      const res = await axios.post(`${apiBase}/api/work/toggleWorkLikeRoute`, { work_id: id, language: langCode }, { headers: { Authorization: authHeader } });
      if (res?.data?.success === true) {
        const d = res.data.data || {};
        const isLiked = typeof d.is_liked !== 'undefined' ? d.is_liked : (typeof d.isLiked !== 'undefined' ? d.isLiked : undefined);
        const likesCount = typeof d.likes_count !== 'undefined' ? d.likes_count : (typeof d.likesCount !== 'undefined' ? d.likesCount : undefined);
        setLikesState((prev) => {
          const base = prev[id] || prevEntry;
          return { ...prev, [id]: { liked: typeof isLiked !== 'undefined' ? !!isLiked : base.liked, count: typeof likesCount !== 'undefined' ? Number(likesCount) : base.count } };
        });
      } else {
        setLikesState((prev) => ({ ...prev, [id]: prevEntry }));
      }
    } catch (e) {
      setLikesState((prev) => ({ ...prev, [id]: prevEntry }));
    }
  }, [likesState, locale, card]);

  // 拉取公开作品
  const fetchWorks = React.useCallback(async (pageToLoad: number, replace = false) => {
    if (!card) return;
    if (loading) return;
    setLoading(true);
    try {
      const templateId = (card as any)?.raw?.id ?? (card as any)?.id ?? 0;
      const langCode = toApiLanguageCode(locale as any);
      const raw = localStorage.getItem('userData');
      const parsed = raw ? JSON.parse(raw) : null;
      const token = parsed?.user_token;
      let res: any;
      if (token) {
        const authHeader = typeof token === 'string' && token.trim().toLowerCase().startsWith('bearer ') ? token : `Bearer ${token}`;
        res = await request.post('/api/template/getPublicWorksByTemplateRoute', {
          template_id: templateId,
          sort: 'likes',
          page: pageToLoad,
          page_size: pageSize,
          language: langCode,
        }, { headers: { Authorization: authHeader } });
      } else {
        res = await request.post('/api/template/getPublicWorksByTemplateRoute', {
          template_id: templateId,
          sort: 'likes',
          page: pageToLoad,
          page_size: pageSize,
          language: langCode,
        });
      }
      if (res?.data?.success === true) {
        const data = Array.isArray(res.data.data) ? res.data.data : [];
        if (pageToLoad === 1 && data.length === 0) {
          setNoUserGenerated(true);
        } else if (replace) {
          setNoUserGenerated(false);
        }
        const mapped = data.map((it: any) => ({
          id: it.id,
          src: it.image_url,
          likes: it.likes_count,
          userName: it.creator?.nickname || '',
          avatar: it.creator?.avatar_url || '',
          raw: it,
        }));

        setWorks((prev) => (replace ? mapped : prev.concat(mapped)));

        setLikesState((prev) => {
          const next = { ...prev };
          mapped.forEach((it: any) => {
            next[it.id] = { liked: !!it.raw?.is_liked, count: Number(it.raw?.likes_count ?? it.likes ?? 0) };
          });
          return next;
        });

        setGridLoadedMap((prev) => {
          const next = { ...prev };
          mapped.forEach((it: any) => {
            if (typeof next[it.id] === 'undefined') next[it.id] = false;
          });
          return next;
        });

        setTotal(Number(res.data.total || 0));
        setPage(Number(res.data.page || pageToLoad));

        const returnedPage = Number(res.data.page || pageToLoad);
        const returnedPageSize = Number(res.data.page_size || pageSize);
        const returnedTotal = Number(res.data.total || 0);
        if (data.length === 0 || (returnedTotal > 0 && returnedPage * returnedPageSize >= returnedTotal)) {
          setNoMore(true);
        } else {
          setNoMore(false);
        }
      }
    } catch (e) {
      // ignore
    } finally {
      setLoading(false);
    }
  }, [card, locale, pageSize, loading]);

  // 当 card/visible/locale 变化时，重置并拉取第一页
  React.useEffect(() => {
    if (!visible || !card) return;
    setWorks([]);
    setPage(1);
    setNoMore(false);
    fetchWorks(1, true);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [card, visible, locale]);

  // 打开列表时请求角色详情（不渲染，仅按需求触发请求）
  React.useEffect(() => {
    if (!visible || !card) return;
    try {
      const templateId = (card as any)?.raw?.id ?? (card as any)?.id ?? 0;
      if (!templateId) return;
      request.post('/api/template/getRoleDetailRoute', { id: templateId }).catch(() => { });
    } catch { }
  }, [visible, card, locale]);

  // 滚动懒加载：监听传入的滚动容器而非 window
  React.useEffect(() => {
    const el = scrollContainerRef.current;
    if (!el) return;
    const handleScroll = () => {
      try {
        if (loading || noMore || !visible) return;
        const scrollTop = el.scrollTop;
        const clientHeight = el.clientHeight;
        const scrollHeight = el.scrollHeight;
        if (scrollTop + clientHeight >= scrollHeight - 200) {
          fetchWorks(page + 1, false);
        }
      } catch (e) { }
    };
    el.addEventListener('scroll', handleScroll as any, { passive: true } as any);
    return () => {
      try { el.removeEventListener('scroll', handleScroll as any); } catch { }
    };
  }, [page, loading, noMore, visible, scrollContainerRef, fetchWorks]);

  return (
    <div className=" w-[100%] m-auto dark:bg-[#2c2c2c] bg-white px-3 py-4 shadow-lg ">
      {/* 卡片网格区域：展示同款的其他卡片（保留原有 UI 结构与样式） */}
      <div className='grid gap-1 grid-cols-2 sm:grid-cols-3 md:grid-cols-3 lg:grid-cols-6'>
        {loading && works.length === 0 ? (
          Array.from({ length: pageSize }).map((_, idx) => (
            <div className="relative dark:bg-[#2c2c2c] border-gray-300 dark:border-[#1c1c1c] bg-white " key={`skeleton-${idx}`}>
              <div style={{ borderRadius: '0.8rem 0.8rem 0 0', overflow: 'hidden', position: 'relative', aspectRatio: ((card as any)?.raw?.image_width || (card as any)?.raw?.width || (card as any)?.raw?.w) && ((card as any)?.raw?.image_height || (card as any)?.raw?.height || (card as any)?.raw?.h) ? `${((card as any)?.raw?.image_width || (card as any)?.raw?.width || (card as any)?.raw?.w)} / ${((card as any)?.raw?.image_height || (card as any)?.raw?.height || (card as any)?.raw?.h)}` : '1 / 1' }}>
                <div className="absolute inset-0 bg-gray-200 dark:bg-gray-700 animate-pulse" />
              </div>
              <div className="absolute w-full  bottom-0  flex justify-between items-center px-2 py-2 bg-gradient-to-t from-black/100 to-transparent">
                <div className="flex items-center">
                  <div className="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 animate-pulse"></div>
                  <div className="ml-2 w-16 h-3 rounded bg-gray-300 dark:bg-gray-600 animate-pulse"></div>
                </div>
                <div className="flex items-center">
                  <div className="w-10 h-4 rounded bg-gray-300 dark:bg-gray-600 animate-pulse"></div>
                </div>
              </div>
            </div>
          ))
        ) : noUserGenerated && !loading ? (
          <div className="col-span-full text-center text-gray-500 dark:text-gray-300 py-8">{t('informationCard.no_user_generated_images')}</div>
        ) : (
          works.map((item) => (
            <div className="relative dark:bg-[#2c2c2c] border-gray-300 dark:border-[#1c1c1c] bg-white " key={item.id} data-work-id={item.id}>
              {/* 图片与骨架 */}
              <div style={{ borderRadius: '0.8rem 0.8rem 0 0', overflow: 'hidden', position: 'relative', aspectRatio: ((item?.raw?.image_width || item?.raw?.width || item?.raw?.w) && (item?.raw?.image_height || item?.raw?.height || item?.raw?.h)) ? `${(item?.raw?.image_width || item?.raw?.width || item?.raw?.w)} / ${(item?.raw?.image_height || item?.raw?.height || item?.raw?.h)}` : undefined }}>
                {!gridLoadedMap[item.id] && (
                  <div className="absolute inset-0 bg-gray-200 dark:bg-gray-700 animate-pulse" />
                )}
                <img
                  src={item.src || ''}
                  alt={item.userName || 'no image'}
                  className="object-contain w-full h-auto block cursor-zoom-in"
                  style={{ borderRadius: '0.8rem 0.8rem 0 0' }}
                  onLoad={() => setGridLoadedMap((prev) => ({ ...prev, [item.id]: true }))}
                  onError={() => setGridLoadedMap((prev) => ({ ...prev, [item.id]: true }))}
                  onClick={() => onOpenPreviewById && onOpenPreviewById(item.id)}
                />
              </div>
              {/* 信息与操作区域 */}
              <div className="absolute w-full  bottom-0  flex justify-between items-center px-2 py-2 bg-gradient-to-t from-black/100 to-transparent">
                <div className="flex items-center">
                  <img src={item.avatar} className="w-6 h-6 rounded-full"></img>
                  <p className="text-[white] dark:text-gray-300 ml-2" title={item.userName}>{sliceByDisplayWidth(item.userName, 6)}</p>
                </div>
                <div className="flex items-center">
                  <button onClick={() => toggleLike(item.id)} className="text-[white] dark:text-white flex items-center">
                    {!likesState[item.id]?.liked ? (
                      <svg viewBox="0 0 1024 1024" width="20" height="20" xmlns="http://www.w3.org/2000/svg" p-id="9610" className="fill-current"><path d="M667.786667 117.333333C832.864 117.333333 938.666667 249.706667 938.666667 427.861333c0 138.250667-125.098667 290.506667-371.573334 461.589334a96.768 96.768 0 0 1-110.186666 0C210.432 718.368 85.333333 566.112 85.333333 427.861333 85.333333 249.706667 191.136 117.333333 356.213333 117.333333c59.616 0 100.053333 20.832 155.786667 68.096C567.744 138.176 608.170667 117.333333 667.786667 117.333333z m0 63.146667c-41.44 0-70.261333 15.189333-116.96 55.04-2.165333 1.845333-14.4 12.373333-17.941334 15.381333a32.32 32.32 0 0 1-41.770666 0c-3.541333-3.018667-15.776-13.536-17.941334-15.381333-46.698667-39.850667-75.52-55.04-116.96-55.04C230.186667 180.48 149.333333 281.258667 149.333333 426.698667 149.333333 537.6 262.858667 675.242667 493.632 834.826667a32.352 32.352 0 0 0 36.736 0C761.141333 675.253333 874.666667 537.6 874.666667 426.698667c0-145.44-80.853333-246.218667-206.88-246.218667z" p-id="9611"></path></svg>
                    ) : (
                      <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9452" width="20" height="20"><path d="M512 901.746939c-13.583673 0-26.122449-4.179592-37.093878-13.061225-8.881633-7.314286-225.697959-175.020408-312.424489-311.379592C133.746939 532.37551 94.040816 471.24898 94.040816 384.522449c0-144.718367 108.146939-262.269388 240.326531-262.269388 67.395918 0 131.657143 30.82449 177.632653 84.636735 45.453061-54.334694 109.191837-84.636735 177.110204-84.636735 132.702041 0 240.326531 117.55102 240.326531 262.269388 0 85.159184-37.093878 143.673469-67.395919 191.216327l-1.044898 1.567346c-86.726531 136.359184-303.542857 304.587755-312.424489 311.379592-10.44898 8.359184-22.987755 13.061224-36.571429 13.061225z" fill="#E5404F" p-id="9453"></path></svg>
                    )}
                    <span className="text-[white] dark:text-gray-300 ml-1">{likesState[item.id]?.count ?? item.likes}</span>
                  </button>
                </div>
              </div>
            </div>
          ))
        )}
      </div>
    </div>
  );
};

export default InformationList;


